package com.youlin.controller;

import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.youlin.aop.AsyncService;
import com.youlin.dto.BaseDataResDto;
import com.youlin.dto.BaseReqDto;
import com.youlin.dto.BaseResDto;
import com.youlin.dto.Status;
import com.youlin.dto.req.SendCodeReqDto;
import com.youlin.dto.req.UpdPwdReqDto;
import com.youlin.dto.req.WxShareReqDto;
import com.youlin.dto.res.OSSResDto;
import com.youlin.dto.res.WxShareResDto;
import com.youlin.entities.BygAppointment;
import com.youlin.entities.BygDeadMan;
import com.youlin.mybean.UnIntercept;
import com.youlin.service.BygAdminService;
import com.youlin.service.BygAppointmentService;
import com.youlin.service.BygDeadManService;
import com.youlin.untils.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiOperationSort;
import io.swagger.annotations.ApiSort;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Constructor;

@ApiSort(2)
@Api(tags = {"2 - 通用接口"})
@RestController
@RequestMapping("/common")
public class CommonController {

    @Autowired
    private WxPublicUtil wxUtil;
    @Autowired
    private OSSUtil ossUtil;
    @Autowired
    private BygAdminService bygAdminService;
    @Autowired
    private BygDeadManService bygDeadManService;
    @Autowired
    private BygAppointmentService bygAppointmentService;
    @Autowired
    private AsyncService asyncService;

    @UnIntercept
    @PostMapping("/reqTooMuch")
    @ApiOperation(value = "", hidden = true)
    public BaseResDto<Status, String> reqTooMuch() {
        return new BaseResDto<>(Status.REQTOOMUCH);
    }

    @UnIntercept
    @PostMapping("/toLogin")
    @ApiOperation(value = "", hidden = true)
    public BaseResDto<Status, String> toLogin() {
        return new BaseResDto<>(Status.UNLOGIN);
    }

    @UnIntercept
    @PostMapping("/updPwdFirst")
    @ApiOperation(value = "", hidden = true)
    public BaseResDto<Status, String> updPwdFirst() {
        return new BaseResDto<>(Status.UPDPWDFIRST);
    }

    @UnIntercept
    @PostMapping("/tokenLogin")
    @ApiOperation(value = "", hidden = true)
    public <T> T tokenLogin(HttpServletRequest request) {
        Constructor<?> constructor = (Constructor<?>) request.getAttribute("Constructor");
        try {
            return (T) constructor.newInstance(Status.NEEDTAKERLOGIN);
        } catch (Exception e) {
            return (T) new BaseResDto<>(Status.ERROR);
        }
    }

    @UnIntercept
    @PostMapping("/smsCodeError")
    @ApiOperation(value = "", hidden = true)
    public BaseResDto<Status, String> smsCodeError(HttpServletRequest request) {
        Status status = (Status) request.getAttribute("status");
        return new BaseResDto<>(status);
    }

    /**
     * 管理平台登录发送手机验证码
     *
     * @param baseReqDto
     * @return
     */
    @UnIntercept
    @PostMapping("/guest/sendCode")
    @ApiOperationSort(1)
    @ApiOperation(value = "1 - 管理平台登录发送手机验证码", notes = "请求参数data = 手机号\n" +
            "响应参数：status-message = {1023-发送验证码请求频繁，1039-阿里云短信服务异常}")
    public BaseResDto<Status, String> sendCode(@RequestBody BaseReqDto<SendCodeReqDto> baseReqDto) {
        SendCodeReqDto data = baseReqDto.getData();
        if (MyBeanUtil.isParamError(data) || !data.getTel().matches("^[1][0-9]{10}$"))
            return new BaseResDto<>(Status.PARAMETERERROR);
        return bygAdminService.sendCode(data.getName(), data.getTel());
    }

    /**
     * 登录用户修改密码
     *
     * @param baseReqDto
     * @return
     */
    @UnIntercept
    @PostMapping("/updPwd")
    @ApiOperationSort(value = 2)
    @ApiOperation(value = "2 - 登录用户修改密码", notes = "响应参数：status-message" +
            " = {1012-密码必须为8-20位数字和字母组合, 1013-原密码错误}")
    public BaseResDto<Status, String> updPwd(@RequestBody BaseReqDto<UpdPwdReqDto> baseReqDto) {
        UpdPwdReqDto data = baseReqDto.getData();
        if (MyBeanUtil.isParamError(data)) return new BaseResDto<>(Status.PARAMETERERROR);
        return bygAdminService.updPwd(data.getAdminId(), data.getOldPwd(), data.getNewPwd());
    }

    /**
     * 获取图形验证码base64数据
     *
     * @return
     */
    @UnIntercept
    @PostMapping("/guest/getCaptchaBase64")
    @ApiOperationSort(value = 3)
    @ApiOperation(value = "3 - 获取图形验证码base64数据")
    public BaseDataResDto<String> getCaptchaBase64() {
        return bygAdminService.getCaptchaBase64();
    }

    /**
     * 校验图形验证码
     *
     * @param baseReqDto
     * @return
     */
    @UnIntercept
    @PostMapping("/guest/validateCaptcha")
    @ApiOperationSort(value = 4)
    @ApiOperation(value = "4 - 校验图形验证码", notes = "请求参数data = 图形验证码")
    public BaseResDto<Status, String> validateCaptcha(@RequestBody BaseReqDto<String> baseReqDto) {
        String code = baseReqDto.getData();
        return bygAdminService.validateCaptcha(code);
    }

    /**
     * 获取OSS上传签名
     *
     * @return
     */
    @PostMapping("/getOSSsignature")
    @ApiOperationSort(value = 5)
    @ApiOperation(value = "5 - 获取OSS上传签名", notes = "请求参数参数：上传逝者相关照片时data=\"deadMan\"，\n" +
            "上传风俗信息相关图片或视频时data=\"custom\"")
    public BaseDataResDto<OSSResDto> getOSSsignature(@RequestBody BaseReqDto<String> baseReqDto) {
        String dir = baseReqDto.getData();
        OSSResDto ossResDto = ossUtil.getOSSsignature(dir);
        return new BaseDataResDto<OSSResDto>(Status.SUCCESS).setData(ossResDto);
    }

    /**
     * OSS上传文件
     *
     * @return
     */
    @PostMapping("/ossUpload")
    @ApiOperationSort(value = 6)
    @ApiOperation(value = "6 - OSS上传文件", notes = "响应参数：data=上传文件url")
    public BaseDataResDto<String> upload(@RequestBody MultipartFile uploadFile) {
        String url = ossUtil.upload(uploadFile);
        if (StringUtils.isBlank(url)) return new BaseDataResDto<>(Status.ERROR);
        return new BaseDataResDto<>(Status.SUCCESS);
    }

    /**
     * 获取微信分享签名
     *
     * @param baseReqDto
     * @return
     */
    @PostMapping("/guest/getWxShare")
    @ApiOperationSort(value = 7)
    @ApiOperation(value = "7 - 获取微信分享签名")
    public BaseDataResDto<WxShareResDto> getWxShare(@RequestBody BaseReqDto<WxShareReqDto> baseReqDto) {
        WxShareReqDto data = baseReqDto.getData();
        if (MyBeanUtil.isParamError(data)) return new BaseDataResDto<>(Status.PARAMETERERROR);
        WxShareResDto wx = wxUtil.getWxShare(data.getUrl());
        LambdaUpdateWrapper<BygAppointment> wrapper = Wrappers.lambdaUpdate(BygAppointment.class)
                .eq(BygAppointment::getUuId, data.getAmUuId());
        BygAppointment appointment = bygAppointmentService.getOne(wrapper);
        BygDeadMan deadMan = bygDeadManService.getById(appointment.getDmId());
        wx.setDmName(deadMan.getName()).setDnGender(deadMan.getGender())
                .setDmHeadUrl(deadMan.getHeadUrl());
        return new BaseDataResDto<WxShareResDto>(Status.SUCCESS).setData(wx);
    }

    /**
     * 获取告别会二维码base64数据
     *
     * @return
     */
    @UnIntercept
    @PostMapping("/guest/getAmBase64")
    @ApiOperationSort(value = 8)
    @ApiOperation(value = "8 - 获取告别会二维码base64数据", notes = "请求参数data = 告别会二维码url")
    public BaseDataResDto<String> getAmBase64(@RequestBody BaseReqDto<String> baseReqDto) {
        String url = baseReqDto.getData();
        if (StringUtils.isBlank(url)) return new BaseDataResDto<>(Status.PARAMETERERROR);
        return bygAppointmentService.getAmBase64(url);
    }

    /**
     * 清除指定本地缓存和Redis缓存
     *
     * @return
     */
    @UnIntercept
    @PostMapping("/guest/cleanAllCache")
    @ApiOperationSort(value = 9)
    @ApiOperation(value = "9 - 清除指定本地缓存和Redis缓存", notes = "请求参数data = 告别会UUID")
    public BaseResDto<Status, String> cleanAllCache(@RequestBody BaseReqDto<String> baseReqDto) {
        String amUuId = baseReqDto.getData();
        if (StringUtils.isBlank(amUuId)) return new BaseDataResDto<>(Status.PARAMETERERROR);
        bygAppointmentService.cleanAllCache(amUuId);
        return new BaseResDto<>(Status.SUCCESS);
    }

    /**
     * 切换微信小程序
     *
     * @return
     */
    @UnIntercept
    @PostMapping("/guest/switchWxApplet")
    @ApiOperationSort(value = 10)
    @ApiOperation(value = "10 - 切换微信小程序", notes = "请求参数data = 微信小程序标识：7cf9683a(中广测试)，" +
            "7cf9683b(中广测试2)，96221d38(中广家书)，7a58e691(中广家信)，adf6614a(中广鸿月)，3d2ef4f5(中广传书)")
    public BaseResDto<Status, String> switchWxApplet(@RequestBody BaseReqDto<String> baseReqDto) {
        String wxActive = baseReqDto.getData();
        if (StringUtils.isBlank(wxActive)) return new BaseDataResDto<>(Status.PARAMETERERROR);
        if (!asyncService.switchWxApplet(wxActive)) return new BaseResDto<>(Status.ERROR);
        return new BaseResDto<>(Status.SUCCESS);
    }

    @UnIntercept
    @PostMapping("/guest/stressTesting")
    @ApiOperationSort(value = 11)
    @ApiOperation(value = "压力测试全链路空接口")
    public BaseResDto<Status, String> stressTesting() {
        return new BaseResDto<>(Status.SUCCESS);
    }

}
